<?php
/*******************************************************************************

    FinalsClub.org is a platform for students and faculty to collaborate
    and share their knowledge with the world.

    Copyright (C) 2009  Andrew Magliozzi
 
    This file is a part of FinalsClub.org.

    FinalsClub.org is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
    To contact FinalsClub.org, send an email to info@finalsclub.org, or
    send mail to Finals Club, c/o Veritas Tutors, 1132 Massachusetts Avenue,
    Cambridge, MA 02138.

*******************************************************************************/

class NotePeer extends BaseNotePeer {
	
	const GROUP = 1;
	const SCHOOL = 2;
	const EVERYONE = 3;
	const BASE_OBJECT_NAME = "Note";
	
	
	public static $visibilityTypes = array(
		self::EVERYONE => 'Everyone',
		self::SCHOOL => 'School',
		self::GROUP => 'Group'
	);

	/**
	 * Toggle the deletion flag on the current live record in the notes table.
	 * @param int $note_id The note ID.
	 * @param boolean $value True for deleted, false for not.
	 * @return boolean True for success, false for failure.
	 * @author CROSCON
	 */
	public static function toggleDeleteCurrent($note_id,$value) {
		$con = Propel::getConnection();
		$value = $value ? 1 : 0;
		$sql = 'update notes set deleted = ? where id = ?';
		$stmt = $con->prepare($sql);
		return $stmt->execute(array($value,$note_id));
	}

	/**
	 * Toggle the deletion flag on a note version.
	 * @param int $note_id The note ID.
	 * @param int $version The version number.
	 * @param boolean True for deleted, false for not.
	 * @return boolean True for success, false for failure.
	 * @author CROSCON
	 */
	public static function toggleDeleteByVersion($note_id,$version,$value) {
		$con = Propel::getConnection();

		$value = $value ? 1 : 0;

		$sql = "select resource_attribute_version.id,resource_version.id as rid from resource_version  join resource_attribute_version_hash on resource_version.id = resource_attribute_version_hash.resource_version_id  join resource_attribute_version on resource_attribute_version.id = resource_attribute_version_hash.resource_attribute_version_id  where resource_version.number=? and resource_version.resource_id=? and resource_attribute_version.attribute_name='Deleted'";

		$stmt = $con->prepare($sql);
		$result = $stmt->execute(array($version,$note_id));

		if(!$result)
			return false;

		$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

		if(!is_array($data) && !count($data))
			return false;

		$data = array_shift($data);
		$attribute = $data['id'];
		$rid = $data['rid'];

		$sql = "insert into resource_attribute_version (attribute_name,attribute_value) values ('Deleted',?)";
		$stmt = $con->prepare($sql);
		$result = $stmt->execute(array($value));

		if(!$result)
			throw new Exception("Insert failed");

		$id = $con->lastInsertId();
		if(!$id)
			throw new Exception("Can't get last ID");

		$sql = "update resource_attribute_version_hash set resource_attribute_version_id = ? where resource_attribute_version_id = ? and resource_version_id = ?";
		$stmt = $con->prepare($sql);
		$result = $stmt->execute(array($id,$attribute,$rid));
		
		if(!$result)
			return false;

		return true;
	}

	/**
	 * Retrieve all notes for a given course. Checks the permissions validates that the user can view the notes 
	 * Effectively does the following:
	 *
	 * SELECT NOTES.* FROM NOTES, COURSES, USERS WHERE notes.course_id = $course_id AND (notes.visibility = NotePeer::EVERYONE OR
	 *	notes.user_id = $user_id OR (visibility = NotePeer::SCHOOL AND courses.network_id = user.network_id AND 
	 * 						notes.course_id = $course_id and users.id = $user_id) OR 
	 *		 (visibility = NotePeer::GROUP AND group_members.user_id = $user_id AND ground_members.group_id = notes.group_id));
	 *
	 * @param $course_id
	 * @param $user_id
	 * @param $page
	 * @param $per_page
	 * @return sfPropelPager object
	 */
	public static function retrieveByCourseIdPager($course_id, $user_id, $page = 1, $per_page = 20) {
		$c = new Criteria();
		$c->add(NotePeer::COURSE_ID, $course_id);
		
		/*
		$extrac = new Criteria();
		$extrac->add(NotePeer::VISIBILITY,NotePeer::EVERYONE);
		
		if($user_id) {
			$extrac->addOr(NotePeer::USER_ID, $user_id);
			
			$ec = new Criteria();
			$ec->add(NotePeer::VISIBILITY,NotePeer::SCHOOL);
			$ec->add(NotePeer::USER_ID, $user_id);
			$ec->add(NotePeer::COURSE_ID, $course_id);
			$ec->addJoin(CoursePeer::NETWORK_ID, UserPeer::NETWORK_ID);

			$extrac->addOr($ec);

			$ec2 = new Criteria();
			$ec2->add(NotePeer::VISIBILITY,NotePeer::GROUP);
			$ec2->addJoin(NotePeer::USER_ID, GroupMemberPeer::USER_ID);
			$ec2->addJoin(GroupMemberPeer::GROUP_ID, NotePeer::GROUP_ID);

			$extrac->addOr($ec2);
		}*/
		
		$c->add(NotePeer::VISIBILITY,NotePeer::EVERYONE);
		$pager = new sfPropelPager('Note', $per_page);
		$pager->setCriteria($c);
		$pager->setPage($page);
		$pager->setPeerMethod('doSelectJoinCourse');
		$pager->init();
		return $pager;

	}
	/**
	 * 
	 * @param $course_id
	 * @param $page
	 * @param $per_page
	 * @return sfPropelPager object
	 */
	public static function retrieveAllByCourseIdPager($course_id, $page = 1, $per_page = 20) {

		$c = new Criteria();
		$c->add(NotePeer::COURSE_ID, $course_id);
		$pager = new sfPropelPager('Note', $per_page);
		$pager->setCriteria($c);
		$pager->setPage($page);
		$pager->setPeerMethod('doSelectJoinCourse');
		$pager->init();
		return $pager;
	}
	
	/**
	 * Retrieve all notes for a given group
	 * @param $group_id
	 * @param $page
	 * @param $per_page
	 * @return sfPager
	 */
	public static function retrieveByGroupIdPager($group_id, $page = 1, $per_page = 20 , $semester_id = false, $lecture=false, $criteria_only = false) {
		$c = new Criteria();
		$c->addJoin(NotePeer::COURSE_ID, GroupCoursePeer::COURSE_ID);
		$c->addJoin(NotePeer::USER_ID, GroupMemberPeer::USER_ID);
		$c->addJoin(GroupMemberPeer::GROUP_ID, GroupCoursePeer::GROUP_ID);
		$c->add(GroupCoursePeer::GROUP_ID, $group_id);
		if ($semester_id){
			$c->add(NotePeer::SEMESTER_ID, $semester_id);
		}
		if ($lecture){
			$c->add(NotePeer::NUMBER, $lecture);
		}
		if ($criteria_only){
			return $c;
		}
		
		$pager = new sfPropelPager('Note', $per_page);
		$pager->setPeerMethod('doSelectJoinCourse');
		$pager->setPage($page);
		$pager->setCriteria($c);
		$pager->init();
		return $pager;
	}
		
		
		
		
		

	
	/**
	 * Retrieve all notes for a given course id and group id
	 * @param $course_id
	 * @param $group_id
	 * @param $page
	 * @param $per_page
	 * @return sfPager
	 */
	public static function retrieveByCourseIdAndGroupIdPager($course_id, $group_id, $page = 1, $per_page = 20, $semester_id = false, $lecture = false, $criteria_only = false) {
		$c = NotePeer::retrieveByGroupIdPager($group_id, $page, $per_page, $semester_id, $lecture, true );
		$c->add(NotePeer::COURSE_ID, $course_id);
		if ($criteria_only){
			return $c;
		}
		$pager = new sfPropelPager('Note', $per_page);
		$pager->setPage($page);
		$pager->setPeerMethod('doSelectJoinCourse');
		$pager->setCriteria($c);
		$pager->init();
		return $pager;
	}
	
	public static function retrieveByCourseIdAndGroupId($course_id, $group_id, $semester_id = false, $lecture = false){
		$c = NotePeer::retrieveByCourseIdAndGroupIdPager($course_id, $group_id, null , null, $semester_id, $lecture, true);
		return 	NotePeer::doSelect($c);
		
	}
	
	/**
	 * Retrieve a single note for a given id
	 * @param $id
	 * @return a single Note object
	 */
	public static function retrieveById($id) {
		$c = new Criteria();
		$c->add(NotePeer::ID, $id);
		$notes = NotePeer::doSelectJoinCourse($c);
		if($notes && isset($notes[0])) {
			return $notes[0];
		} else {
			return null;
		}
	}
	
	/**
	 * Retrieve all notes for a given user id
	 * @param $user_id
	 * @return sfPager
	 */
	public static function retrieveByUserIdPager($user_id, $page=1, $per_page = 10) {
		$c = new Criteria();
		$c->add(NotePeer::USER_ID, $user_id);
		$c->addDescendingOrderByColumn(NotePeer::ID);
		$pager = new sfPropelPager('Note', $per_page);
		$pager->setPage($page);
		$pager->setCriteria($c);
		$pager->setPeerMethod('doSelectJoinCourse');
		$pager->init();
		return $pager;
	}
	
	/**
	 * Suppose to retrieve all popular public notes. For now it retrieves a pre-determined set
	 * @param $limit
	 * @return array of Note objects
	 */
	public static function retrieveAllPublic($limit = null) {
		$c = new Criteria();
		$c->add(NotePeer::VISIBILITY, NotePeer::EVERYONE);
		if($limit) {
			$c->setLimit($limit);
 		}
 		return NotePeer::doSelect($c); 		
	}
	
	/**
	 * Retrieves the count of notes for a given subject
	 * @param $subject_id
	 * @param $visibility
	 * @return unknown_type
	 */
	public static function countForSubjectId($subject_id, $visibility = NotePeer::EVERYONE) {
		$c = new Criteria();
		$c->addJoin(NotePeer::COURSE_ID, CoursePeer::ID);
		$c->addJoin(CoursePeer::SUBJECT_ID, SubjectPeer::ID);
		$c->add(SubjectPeer::ID, $subject_id);
		$c->add(NotePeer::VISIBILITY, $visibility);
		return NotePeer::doCount($c);
	}

	/**
	 * Method to DELETE all rows from the notes table.
	 * Overrides the BaseNotePeer doDeleteAll
	 *
	 * @return     int The number of affected rows (if supported by underlying database driver).
	 * @see	   BaseNotePeer::doDeleteAll()
	 */
	public static function doDeleteAll($con = null)
	{
		if (file_exists($index = Search::getLuceneIndexFile(Search::NOTE))) {
    			sfToolkit::clearDirectory($index);
    			rmdir($index);
  		}
		return parent::doDeleteAll($con);
	}
	
	
	//retrieve by user id and module name
	public static function retrieveByUserIdAndType($user_id, $type)
	{
		$c = new Criteria();
		$c->add(NotePeer::USER_ID, $user_id);
		$c->add(NotePeer::TYPE, $type);
		return NotePeer::doSelect($c);
	}
	
	//retrieve by user id and the day it was created as a timestamp
	public static function retrieveByUserIdAndDate($user_id, $time_stamp)
	{
		$c = new Criteria();
		$c->add(NotePeer::USER_ID, $user_id);
		$c->add(NotePeer::CREATED_AT, date('Y-m-d', $time_stamp), Criteria::GREATER_EQUAL);
		$c->addAnd(NotePeer::CREATED_AT, date('Y-m-d', $time_stamp + 60*60*24), Criteria::LESS_THAN);
		
 		return NotePeer::doSelect($c); 		
	
	}
	
	//retrieve by group id and the day it was created as a timestamp
	public static function retrieveByGroupIdAndCreatedAt($group_id, $time_stamp)
	{
		$c = new Criteria();
		$c->add(NotePeer::GROUP_ID, $group_id);
		$c->add(NotePeer::CREATED_AT, date('Y-m-d', $time_stamp), Criteria::GREATER_EQUAL);
		$c->addAnd(NotePeer::CREATED_AT, date('Y-m-d', $time_stamp + 60*60*24), Criteria::LESS_THAN);
		
		
 		return NotePeer::doSelect($c); 		
	
	}
	
	
	public static function retrieveAllPublicByCreatedAt($time_stamp) {
		$c = new Criteria();
		$c->add(NotePeer::VISIBILITY, NotePeer::EVERYONE);
		$c->add(NotePeer::GROUP_ID, NULL);
		$c->add(NotePeer::CREATED_AT, date('Y-m-d', $time_stamp), Criteria::GREATER_EQUAL);
		$c->addAnd(NotePeer::CREATED_AT, date('Y-m-d', $time_stamp + 60*60*24), Criteria::LESS_THAN);
		
 		return NotePeer::doSelect($c); 		
	}
	
	//retrieve by user id and the day it was created as a timestamp
	public static function retrieveByUserId($user_id)
	{
		$c = new Criteria();
		$c->add(NotePeer::USER_ID, $user_id);
 		return NotePeer::doSelect($c); 		
	}
}
